package pl.grabar.clinic.client.web.actions.reception.patient;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;

import pl.grabar.clinic.core.dao.Dao;
import pl.grabar.clinic.core.domain.person.Patient;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.Validateable;

@Action("save")
@InterceptorRef("grabarStack")
@Results({ @Result(name = "success", type = "redirectAction", location = "list"), @Result(name = "input", location = "edit.jsp") })
public class SavePatientAction extends ActionSupport implements Preparable, Validateable {

	private static final long serialVersionUID = 3427383064003952511L;

	private static final Log LOG = LogFactory.getLog(SavePatientAction.class);

	@Autowired
	private Dao<Patient> patientDao;

	private Patient patient;

	private Patient existingPatient;

	private String patientId;

	@Override
	public void prepare() throws Exception {
		if (StringUtils.isNoneBlank(patientId) && NumberUtils.isNumber(patientId)) {
			existingPatient = patientDao.findById(patientId);
		}
System.out.println(new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(patient));
	}

	@Override
	public void validate() {
		if (!hasErrors()) {
			if (StringUtils.isNotBlank(patientId) && existingPatient == null) {
				addActionError(getText("pl.grabar.clinic.client.web.reception.patient.actions.no-such-patient"));
				LOG.error("Blad walidacji w trakcie zapisu pacjenta. Pacjent o podanym id nie istnieje: " + patientId);
			}
			if(patient.getAge() < 0 && patient.getAge() > 130){
				addFieldError("patient.age", getText("Nieprawidłowa wartość"));
				return;
			}
		}
	}

	@Override
	public String execute() throws Exception {
		if (existingPatient != null) {
			updatePatient();
		} else {
			savePatient();
		}
		return SUCCESS;
	}

	private void savePatient() throws Exception {
		patientDao.save(patient);
		addActionMessage(getText("pl.grabar.clinic.client.web.reception.patient.actions.save.saved", new String[] { patient.getFirstName() + " "
				+ patient.getLastName() }));
		LOG.info("Dodano pacjenta o id: " + patient.getId() + ":" + patient.getFirstName() + ":" + patient.getLastName());
	}

	private void updatePatient() throws Exception {
		existingPatient.setAddress(patient.getAddress());
		existingPatient.setAge(patient.getAge());
		existingPatient.setDateOfBirth(patient.getDateOfBirth());
		existingPatient.setFirstName(patient.getFirstName());
		existingPatient.setGender(patient.getGender());
		existingPatient.setLastName(patient.getLastName());
		existingPatient.setPesel(patient.getPesel());
		existingPatient.setPhoneNumber(patient.getPhoneNumber());

		patientDao.update(existingPatient);
		addActionMessage(getText("pl.grabar.clinic.client.web.reception.patient.actions.save.updated", new String[] { existingPatient.getFirstName() + " "
				+ existingPatient.getLastName() }));
		LOG.info("Zaktualizowano pacjenta o id: " + existingPatient.getId() + ":" + existingPatient.getFirstName() + ":" + existingPatient.getLastName());

	}

	/* AKCESORY */

	public Patient getPatient() {
		return patient;
	}

	public void setPatient(Patient patient) {
		this.patient = patient;
	}

	public void setPatientDao(Dao<Patient> patientDao) {
		this.patientDao = patientDao;
	}

	public Patient getExistingPatient() {
		return existingPatient;
	}

	public void setExistingPatient(Patient existingPatient) {
		this.existingPatient = existingPatient;
	}

	public String getPatientId() {
		return patientId;
	}

	public void setPatientId(String patientId) {
		this.patientId = patientId;
	}

}
